import mechanize
import re, logging
import time, os
from datetime import datetime
import sys, traceback
import getopt
from Calculate import calculate
from Config import *

configObj = None
iterations = 0
curIters = 0
def handleError(extraMessage=""):
    (ex_type,ex_value,ex_tb) = sys.exc_info()
    lst = traceback.extract_tb(ex_tb)
    lst = traceback.format_list(lst)
    logging.fatal(extraMessage+" "+str(ex_type)+": "+str(ex_value)+": "+str(lst))
    print "exc_traceback: ",sys.exc_traceback.tb_frame
    print "exc_type: ",sys.exc_type
    print "exc_value: ",sys.exc_value
    pass

def initBrowser():
    print "Initialize Browser"
    br = mechanize.Browser(factory=mechanize.RobustFactory())
    br.set_handle_robots(False)
    return br

def login(br):
#######  Login  #######
    print "Login"
    br.open("https://tools.cleanpowerfinance.com/user/login")
    br.select_form("loginform")
    br["username"] = configObj.getProperty("username")
    br["password"]=configObj.getProperty("password")
    br.submit()
    return br

def getUserPage(br):
    print "Get Helios Page"
#######  Search for Test Customer  #######
    br.select_form(nr=1)
    br["keyword"]="Helios"
    response = br.submit()
#######  Manage the customers settings  #######
    myLink = None
    for link in br.links(url_regex="estimate.php*"):
        #print link
        myLink = link
    response = br.follow_link(myLink)
    return br

def gotoScreen(br, screen):
    print "going to "+screen
    screens = ["summary", "location", "energy", "equip", "analysis", "review","proposal"]
    br.select_form(nr=0)
    br.find_control("nextpage").readonly = False
    br["nextpage"] = screen
    br.submit()
    return br

def fillLocation(br, lstTilt, lstAzimuth, lstShading):
#######  Go to the correct screen  #######
    assert len(lstTilt)==len(lstAzimuth) and len(lstShading)==len(lstTilt)
    print "Filling Location Tab"
    br.select_form(nr=0)
    br.find_control("nextpage").readonly = False
    br["nextpage"]="location"
    response = br.submit()
    br.select_form(nr=0)
    br.set_all_readonly(False)
    br["siteassessment"] = [configObj.getProperty("siteassessment")]
    br["cutility1"] = [configObj.getProperty("cutility1")]
    br["usetou"] = [configObj.getProperty("usetou")]
    for i in xrange(len(lstTilt)):
        br["cheight"+str(i+1)] = "500"
        br["clength"+str(i+1)] = "500"
        br["inoct"+str(i+1)] = ["44"]
        br["tilt"+str(i+1)] = [str(lstTilt[i])]
        br["azimuth"+str(i+1)] = [lstAzimuth[i]]
        for j in xrange(12):
            br["shade"+str(i+1)+str(j+1)] = lstShading[i]
    br["soiling"] = [configObj.getProperty("soiling")]
    br.submit();
    return br

def fillEnergy(br):
    print "Filling Energy Tab"
    br.select_form(nr=0)
    br.find_control("nextpage").readonly = False
    br["nextpage"]="equip"
    br["presolarrate1"] = [configObj.getProperty("presolarrate1")]
    br["euse1"] = configObj.getProperty("euse1")
    br["euse2"] = configObj.getProperty("euse2")
    br["euse3"] = configObj.getProperty("euse3")
    br["euse4"] = configObj.getProperty("euse4")
    br["euse5"] = configObj.getProperty("euse5")
    br["euse6"] = configObj.getProperty("euse6")
    br["euse7"] = configObj.getProperty("euse7")
    br["euse8"] = configObj.getProperty("euse8")
    br["euse9"] = configObj.getProperty("euse9")
    br["euse10"] = configObj.getProperty("euse10")
    br["euse11"] = configObj.getProperty("euse11")
    br["euse12"] = configObj.getProperty("euse12")
    response = br.submit()
    return br

def fillEquip(br):
    print "Filling Equip Tab"
    br.select_form(nr=0)
    br.find_control("nextpage").readonly = False
    br["nextpage"]="analysis"
    br["collectorid"] = [configObj.getProperty("collectorid")]
    br["inverterid"] = [configObj.getProperty("inverterid")]
    br["crate1"]=[configObj.getProperty("crate1")]
    if configObj.getProperty("csistep9")=="1":
        br["incent2616"] = [configObj.getProperty("csistep9")]
    elif configObj.getProperty("csistep10")=="1":
        br["incent2617"] = [configObj.getProperty("csistep10")]
    br["incent499"] = [configObj.getProperty("fedtaxcredit")]
    br.submit()
    return br

def fillAnalysis(br, panels, kwh, designFactor):
    print "Filling Analysis Tab"
    br.select_form(nr=0)
    br.find_control("nextpage").readonly = False
    br["nextpage"] = "review"
    br["nummod1"] = panels
    br["kwh1"] = kwh
    br["numinverter1"] = panels
    br["dsnfactor1"] = designFactor
    response = br.submit()
    return (br, response)

def fetchData(outputFile, br, azimuth="90",shading="100"):
    panelInverterCounts = configObj.panelInverterCounts
    systemSizes = configObj.systemSizes
    designFactors = configObj.designFactors
    instThisYear = configObj.getProperty("installthisyear")
    lstTilt = [20]
    lstAzimuth = [azimuth]
    lstShading = [shading]
#######  We should be on the customers screen here  #######
    br = fillLocation(br, lstTilt, lstAzimuth, lstShading)
#######  We should be on the Energy screen here  #######
    br = fillEnergy(br)
#######  We should be on the Equip screen here  #######    
    br = fillEquip(br)
#######  We should be on the Analysis screen here  #######
    for panelCount in panelInverterCounts:
        systemSize = systemSizes[panelCount]
        designFactor = designFactors[azimuth, shading]
        (br, response) = fillAnalysis(br, panelCount, systemSize, designFactor)
#######  We should be on the Review screen here  #######
        html = response.read()
        csi = html.split('<td align="right" class="rebate_original_postcontract" original="')
        csi = csi[1]
        csi = csi.split(">")[1]
        csi = csi.split("<")[0]
        csi = csi.replace(",","")
        #print "CSI = " + csi
        production = html.split('<td align="right">Estimated Annual Production</td>')[1]
        production = production.split("</td>")[0]
        production = production.replace('<td align="left">',"")
        production = production.strip()
        production = production.replace(",","")
        #print "production =" +production
        br.select_form(nr=0)
        br.find_control("nextpage").readonly = False
        br["nextpage"]="proposal"
        if instThisYear == True:
            instThisYear = "1"
        else:
            instThisYear = "0"
        annualIncreases = configObj.annualIncreases
        initialPayments = configObj.initialPayments
        grossMarginValues = configObj.grossMarginValues
        
        for initialPayment in initialPayments:
            for escalator in annualIncreases:
                for gmv in grossMarginValues[panelCount]:
                    data = calculate(br, gmv, escalator, initialPayment, instThisYear)
                    grossMarginActual = data[0]
                    systemPrice = data[1].replace(",","")
                    ppkwh = data[2].replace(",","")
                    initialPayment = data[3].replace(",","")
                    preSolarMonthlyCost = data[4].replace(",","")
                    postSolarMonthlyCost = data[5].replace(",","")
                    finPaymentPlusUtility = data[6].replace(",","")
                    monthlySavings = data[7].replace(",","")
                    payback = data[8].replace(",","")
                    financePayment = data[6].split(" ")
                    financePayment = financePayment[0]
                    financePayment = financePayment.replace("($","").replace(",","")
                    #print azimuth + " " + shading + " " + initialPayment
                    outputFile.write(systemSize+","+ initialPayment+","+
                                     escalator+","+ gmv+","+systemPrice+","+
                                     azimuth+","+ shading+","+
                                     designFactor+","+ csi+","+
                                     production+","+ ppkwh+","+
                                     financePayment+"\n")
                    #print "record complete\n"
                    global curIters
                    curIters += 1
                    logging.info("Finished %d iterations of %d"%(curIters, iterations))
                    print "Finished %d iterations of %d"%(curIters, iterations)
                    time.sleep(1)
        response = br.open("https://tools.cleanpowerfinance.com/secure/dashboard.php")
        br = getUserPage(br)
        br = gotoScreen(br, "analysis")

def addUserSummary(br):
    br.select_form("jobscript")
    br.find_control("nextpage").readonly = False
    br["nextpage"]="location"
    br["ctype"]=[configObj.getProperty("ctype")]
    br["jobref"]=configObj.getProperty("jobref")
    br["cfirstname"]=configObj.getProperty("cfirstname")
    br["clastname"]=configObj.getProperty("clastname")
    br["cphone1"]=configObj.getProperty("cphone1")
    br["cemail"]=configObj.getProperty("cemail")
    br["caddress1"]=configObj.getProperty("caddress1")
    br["ccity"]=configObj.getProperty("ccity")
    br["czip"]=configObj.getProperty("czip")
    response = br.submit()
    print response.read()
    return br

def usage():
    print "FILL THIS IN LATER"

def main(argv):
    try:
        t = time.ctime()
        t = t.replace(":",".")
        fn = "Logs\\%s.log"%(t)
        d = os.path.dirname("Logs\\")
        if not os.path.exists(d):
            os.makedirs(d)
        logging.basicConfig(filename=fn,level=logging.DEBUG,format='%(levelname)s:%(message)s')
        try: 
            opts, args = getopt.getopt(argv, "c:h",["configfile=", "help"])
        except getopt.GetoptError:
            print "Invalid Arguments."
            usage()
            finish = raw_input("Press Enter to finish!")
            logging.fatal("System Crashed geting option values: "+str(e))
            sys.exit(2)
        print "Checking inputs"
        logging.info("Checking inputs")
        configFilePassed = False
        configFile = "config.txt"
        for opt, arg in opts:
            if opt in ("-h", "--help"):
                usage()
                sys.exit()
            elif opt in ("-c", "--configFile="):
                configFile = arg
                configFilePassed = True
            else:
                print "unhandled option: %s, %s"%(opt, arg)
                logging.fatal("unhandled option: %s, %s"%(opt, arg))
                sys.exit(2)
        global configObj
        try:
            configObj = Config(configFile)
        except IOError as e:
            #print e
            handleError("IOERROR: configFile(%s) may be missing. "%(configFile))
            #logging.fatal("IOERROR: configFile(%s) may be missing. %s"%(configFile, str(e))
            x = raw_input("Press Enter to finish!")
            sys.exit(2)
        br = initBrowser()
        br = login(br)
        br.open("https://tools.cleanpowerfinance.com/secure/dashboard.php")
        br = getUserPage(br)
        now = str(datetime.now())
        now = now.split(" ")[0]
        print "output\\"+now+".csv"
        
        azimuthVals = configObj.azimuthValues
        shadingVals = configObj.shadingValues

        # Calculate the number of iterations needed
        panCount = configObj.panelInverterCounts
        gmvs = configObj.grossMarginValues
        gmvIterations = 0
        for pan in panCount:
            gmvIterations+=len(gmvs[pan])
        global iterations
        iterations= len(azimuthVals)*len(shadingVals)*len(configObj.panelInverterCounts) \
                    * len(configObj.annualIncreases)* len(configObj.initialPayments) \
                    * gmvIterations
        d = os.path.dirname("output\\")
        if not os.path.exists(d):
            os.makedirs(d)
        print os.getcwd()
        with open("output\\"+now+".csv", 'w') as outputFile:
            outputFile.write("System Size,Down,Escalator,Gross Margin,Gross Price,Azimuth,Shade,Design Factor,CSI,Production,PPKWH,Pmt/mo\n")
            for azimuthVal in azimuthVals:
                for shade in shadingVals:
                    results = fetchData(outputFile, br, azimuthVal,shade)
            print "Finished: Closing File"
    #except BadStatusLine as e:
    #    handleError("")
    #    print "BadStatusLine: This means the connection timed out due to a slow connection.  Just try again soon."
    except:
        handleError("General Crash. ")
    finally:
        x = raw_input("Press Enter when finished!")
  
if __name__=="__main__":
  main(sys.argv[1:])
